﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Sharp.Infrastructure;
using Sharp.Infrastructure.Communication;
using Sharp.Platform.Configuration;
using Sharp.Platform.Owin;
using Sharp.ServiceContracts;
using Sharp.WebBooter.Areas.CMS.Models;

namespace Sharp.WebBooter.Areas.CMS.Controllers
{
    //[Authorize]
    public class AccountController : Controller
    {
        //
        // GET: /Account/Login
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
            ViewBag.ReturnUrl = returnUrl;

            var model = new LoginViewModel
            {
                Name = CookieHelper.GetCookie("LoginedName")
            };

            return View(model);
        }

        //
        // POST: /Account/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
#if DEBUG
            if (WebServer.GetIP() != "127.0.0.1")
#endif
            {
                if (System.Web.HttpContext.Current.Session["ValidateCode"] == null)
                {
                    ModelState.AddModelError("", "验证码失效，请重新登录");
                    return View(model);
                }
                if (System.Web.HttpContext.Current.Session["ValidateCode"].ToString() != model.ValidateCode)
                {
                    ModelState.AddModelError("", "验证码错误");
                    return View(model);
                }
            }

            var result = await SignInManager.PasswordSignInAsync(model.Name, model.Password, model.RememberMe, false);

            ContactContext.Current.SystemCode = "CMS";

            switch (result)
            {
                case SignInStatus.Success:


                    using (var proxy = new ServiceProxy<IUserService>())
                    {
                        var res = proxy.Channel.GetUserByName(model.Name);
                        ContactContext.Current.UserId = res.Data.Id;
                        ContactContext.Current.UserName = res.Data.UserName;

                        SharpUserManager.Current = new SharpUser(res.Data);
                    }

                    CookieHelper.SetCookie("LoginedName", model.Name, 36000);

                    return Redirect("~/");
                case SignInStatus.LockedOut:
                    return View("Lockout");
                case SignInStatus.RequiresVerification:
                    return RedirectToAction("SendCode", new {ReturnUrl = returnUrl, model.RememberMe});
                case SignInStatus.Failure:
                default:
                    ModelState.AddModelError("", "无效的登录尝试。");
                    return View(model);
            }
        }

        public ActionResult LogOff()
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
            return RedirectToAction("Login");
        }

        #region 验证码

        [AllowAnonymous]
        public ActionResult GetValidateCode()
        {
            var vCode = new ValidateCode();
            var code = vCode.CreateValidateCode(4);
            Session["ValidateCode"] = code;
            var bytes = vCode.CreateValidateGraphic(code);
            return File(bytes, @"image/jpeg");
        }

        #endregion

        /// <summary>
        ///     忘记密码
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult ForgotPassword()
        {
            var model = new ForgotPasswordViewModel();
            return View("ForgotPassword", model);
        }

        ///// <summary>
        ///// 取回密码
        ///// </summary>
        ///// <param name="vm"></param>
        ///// <returns></returns>
        //[HttpPost]
        //public ActionResult ForgotPassword(ForgotPasswordViewModel vm)
        //{
        //    using (var proxy = new ServiceProxy<IUserService>())
        //    {
        //        var config = SystemConfigManage.Read<SystemInfo>();
        //        SmtpClient smtp = new SmtpClient
        //        {
        //            Credentials = new NetworkCredential(config.EMailConfig.LoginName, config.EMailConfig.Password),
        //            Port = 25,
        //            Host = config.EMailConfig.SmtpServer,
        //            EnableSsl = false
        //        };

        //        //proxy.SendEMail(vm.Email, config.EMailConfig.FromEMail, smtp);

        //        return View(vm);
        //    }
        //}

        /// <summary>
        ///     重置密码
        /// </summary>
        /// <param name="token">防伪识别码</param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult ResetPassword(Guid token)
        {
            var vm = new ResetPasswordViewModel
            {
                AntiForgeryToken = token.ToString()
            };
            return View(vm);
        }

        ///// <summary>
        ///// 重置密码
        ///// </summary>
        ///// <param name="vm"></param>
        ///// <returns></returns>
        //[HttpPost]
        //public ActionResult ResetPassword(ResetPasswordViewModel vm)
        //{
        //    if (vm == null)
        //    {
        //        ModelState.AddModelError("", "提交数据出错。");
        //        return View(new ResetPasswordViewModel());
        //    }
        //    var proxy = ServiceLocator.Instance.GetService<IUserService>();

        //    var res = proxy.ResetPassword(vm.To<ResetPasswordDTO>());
        //    if (res.Err.Length > 0)
        //        ModelState.AddModelError("", res.Err);

        //    return View(vm);
        //}
        /// <summary>
        ///     配置订阅项
        /// </summary>
        /// <returns></returns>
        public ActionResult SubscriberSetting()
        {
            var userId = SharpUserManager.Current.Id;
            var permissions =
                SharpUserManager.Current.Permissions.Where(x => x.SystemCode == "CMS" && x.Category == "09").ToList();
            var config = UserConfigManage.Read<UserConfig>(userId);

            var list = new List<SubscriberSettingViewModel>();
            permissions.ForEach(x =>
            {
                list.Add(new SubscriberSettingViewModel
                {
                    Id = x.Id,
                    Title = x.Title,
                    Url = x.Route,
                    Checked = config.Subscribers.Any(p => p.Id == x.Id) ? "checked" : ""
                });
            });
            return View(list);
        }

        /// <summary>
        ///     保存订阅项配置
        /// </summary>
        /// <returns></returns>
        public ActionResult SaveSubscriber(Guid[] subscriberIds)
        {
            var res = new Result();
            try
            {
                var userId = SharpUserManager.Current.Id;
                var config = UserConfigManage.Read<UserConfig>(userId);
                config.Subscribers.Clear();
                for (var i = 0; i < subscriberIds.Length; i++)
                {
                    config.Subscribers.Add(new UserConfig.SubscriberItem
                    {
                        Id = subscriberIds[i],
                        Order = i
                    });
                }

                UserConfigManage.Save(config);
            }
            catch (Exception ex)
            {
                res.InnerException = ex;
            }
            return Json(res);
        }

        [HttpGet]
        public ActionResult ChangePassword()
        {
            var model = new ChangePassword();
            return View("ChangePassword", model);
        }

        [HttpPost]
        public JsonResult ChangePassword(ChangePassword vm)
        {
            if (vm == null)
            {
                return Json(new Result {Err = "提交数据出错。"});
            }
            if (vm.PasswordNew != vm.PasswordNewS)
            {
                return Json(new Result {Err = "两次输入新密码不一致，请重新输入！"});
            }
            using (var proxy = new ServiceProxy<IUserService>())
            {
                var res = proxy.Channel.ChangePassword(SharpUserManager.Current.UserName, vm.Password, vm.PasswordNew);

                return Json(res);
            }
        }

        #region 帮助程序

        private SharpSignInManager _signInManager;
        private SharpUserManager _userManager;
        // 用于在添加外部登录名时提供 XSRF 保护
        private const string XsrfKey = "XsrfId";

        public SharpSignInManager SignInManager
        {
            get { return _signInManager ?? HttpContext.GetOwinContext().Get<SharpSignInManager>(); }
            private set { _signInManager = value; }
        }

        public SharpUserManager UserManager
        {
            get { return _userManager ?? HttpContext.GetOwinContext().GetUserManager<SharpUserManager>(); }
            private set { _userManager = value; }
        }

        private IAuthenticationManager AuthenticationManager
        {
            get { return HttpContext.GetOwinContext().Authentication; }
        }

        private void AddErrors(IdentityResult result)
        {
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError("", error);
            }
        }

        private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            return RedirectToAction("Index", "Home");
        }

        internal class ChallengeResult : HttpUnauthorizedResult
        {
            public ChallengeResult(string provider, string redirectUri)
                : this(provider, redirectUri, null)
            {
            }

            public ChallengeResult(string provider, string redirectUri, string userId)
            {
                LoginProvider = provider;
                RedirectUri = redirectUri;
                UserId = userId;
            }

            public string LoginProvider { get; set; }
            public string RedirectUri { get; set; }
            public string UserId { get; set; }

            public override void ExecuteResult(ControllerContext context)
            {
                var properties = new AuthenticationProperties {RedirectUri = RedirectUri};
                if (UserId != null)
                {
                    properties.Dictionary[XsrfKey] = UserId;
                }
                context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
            }
        }

        #endregion
    }
}